package uy.com.tsi2G7.superbet.event.dao;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;

import uy.com.tsi2G7.superbet.event.Event;
import uy.com.tsi2G7.superbet.event.EventMarket;
import uy.com.tsi2G7.superbet.event.EventMarketResult;
import uy.com.tsi2G7.superbet.event.EventSource;
import uy.com.tsi2G7.superbet.event.EventType;

public class EventStoreImpl implements EventStore {
	
	private HibernateTemplate hibernateTemplate;

	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Event> getAllEvents() {
		return hibernateTemplate.find("from Event");
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<EventType> getAllEventTypes() {
		return hibernateTemplate.find("from EventType");
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<EventMarket> getCurrentMarketsByEventId(Long eventId, Long eventTypeId) {
		return hibernateTemplate.find("from EventMarket where eventId=? and eventTypeId=? and startDate > ?"
				,new Object[]{eventId,eventTypeId,new Date()});
	}

	@Override
	public List<EventMarketResult> getMarketsWithPendingResults(long marketId) {
		return hibernateTemplate.find("from EventMarketResult where marketId=?",marketId);
	}

	@Override
	public EventMarket getMarketById(long marketId) {
		return (EventMarket) hibernateTemplate.get(EventMarket.class,marketId);
	}

	@Override
	public void storeMarketResult(long marketResultId, String marketResultName,
			long marketId, long eventId, long eventTypeId, BigDecimal amount) throws ObjectAlreadyExistsException {
		if(hibernateTemplate.get(EventMarketResult.class, Long.valueOf(marketResultId))!=null)
			throw new ObjectAlreadyExistsException("marketResult.already.exist");
		EventMarketResult result = new EventMarketResult();
		result.setEventId(eventId);
		result.setEventTypeId(eventTypeId);
		result.setAmount(amount);
		result.setId(marketResultId);
		result.setName(marketResultName);
		result.setMarketId(marketId);
		result.setWinAmount(BigDecimal.valueOf(-1));
		result.setSource(EventSource.MANUAL);
		hibernateTemplate.save(result);
		
		
	}

	@Override
	public Event getEventById(long eventId) {
		return (Event) hibernateTemplate.get(Event.class,eventId);
	}

	@Override
	public EventType getEventTypeById(long eventTypeId) {
		return (EventType) hibernateTemplate.get(EventType.class,eventTypeId);	}

	@Override
	public void storeEvent(Long eventTypeId, long eventId, String eventInputName)
			throws ObjectAlreadyExistsException {
		if(hibernateTemplate.get(Event.class, Long.valueOf(eventId))!=null)
			throw new ObjectAlreadyExistsException("event.already.exist");
		Event event = new Event();
		event.setId(eventId);
		event.setEventTypeId(eventTypeId);
		event.setName(eventInputName);
		event.setSource(EventSource.MANUAL);
		hibernateTemplate.save(event);
		
	}

	@Override
	public void storeMarket(Long eventId, Long eventTypeId, long marketId,
			String marketInputName, Date marketDate) throws ObjectAlreadyExistsException {
		if(hibernateTemplate.get(EventMarket.class, Long.valueOf(marketId))!=null)
			throw new ObjectAlreadyExistsException("market.already.exist");
		EventMarket market = new EventMarket();
		market.setMarketId(marketId);
		market.setEventTypeId(eventTypeId);
		market.setEventId(eventId);
		market.setName(marketInputName);
		market.setStartDate(marketDate);
		market.setSource(EventSource.MANUAL);
		hibernateTemplate.save(market);
		
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<EventMarketResult> getMarketResultsById(final List<Long> ids) {
		return hibernateTemplate.executeFind(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				org.hibernate.Query query = session.createQuery("from EventMarketResult where id in (:ids)");
				query.setParameterList("ids", ids);
				return query.list();
			}
		});
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<EventMarket> getManualSourceMarketsWithPendingResults() {
		return hibernateTemplate.find("from EventMarket where source= ? and startDate < ? and id in (select marketId from EventMarketResult where winAmount = ?)"
				,new Object[]{EventSource.MANUAL,new Date(),BigDecimal.valueOf(-1D)});
	}

	@Override
	public void mergeResult(EventMarketResult eventMarketResult) {
		hibernateTemplate.merge(eventMarketResult);
	}

}
